"use client";

import React, { forwardRef, useImperativeHandle, useState } from "react";

export interface GameData {
  index: number;
  name: string;
  desc: string;
  img: string;
}

export interface GameImgData {
  img: HTMLImageElement;
  x: number;
  y: number;
  gameData: GameData;
  index: number;
  opacity: number;
  loaded: boolean;
}

export interface AnimatingGameImageRef {
  startSelectAnimation: (clickedImage: GameImgData) => void;
  startDeselectAnimation: (selectedImg: GameImgData) => void;
  isAnimating: () => boolean;
}

interface AnimatingGameImageProps {
  selectedImage: GameImgData | null;
  imgWidth: number;
  imgHeight: number;
  canvasRef: React.RefObject<HTMLCanvasElement | null>;
  animationFrameRef: React.RefObject<number | null>;
  imgDataRef: React.MutableRefObject<GameImgData[]>;
  drawAll: () => void;
  setSelectedImage: React.Dispatch<React.SetStateAction<GameImgData | null>>;
}

const AnimatingGameImage = forwardRef<
  AnimatingGameImageRef,
  AnimatingGameImageProps
>((props, ref) => {
  const {
    selectedImage,
    imgWidth,
    imgHeight,
    canvasRef,
    animationFrameRef,
    imgDataRef,
    drawAll,
    setSelectedImage,
  } = props;

  const [animatingImage, setAnimatingImage] = useState<{
    img: GameImgData;
    startX: number;
    startY: number;
    targetX: number;
    targetY: number;
    startTime: number;
    currentX: number;
    currentY: number;
    startScale: number;
    targetScale: number;
    currentScale: number;
    startRotation: number;
    targetRotation: number;
    currentRotation: number;
    trails?: Array<{
      x: number;
      y: number;
      scale: number;
      opacity: number;
      delay: number;
    }>;
  } | null>(null);

  // 开始选中动画
  const startSelectAnimation = (clickedImage: GameImgData) => {
    if (animatingImage) return; // 如果正在动画中，忽略

    const rect = canvasRef.current?.getBoundingClientRect();
    if (!rect) return;

    setSelectedImage(clickedImage);

    // 选中的图片立即变成透明度0，其他图片保持可见准备动画
    imgDataRef.current.forEach((imgData) => {
      if (imgData.index === clickedImage.index) {
        imgData.opacity = 0; // 选中的图片立即消失
      }
    });

    // 立即重绘以显示透明度变化
    drawAll();

    // 计算canvas中图片的绝对位置（考虑canvas的缩放）
    const canvasScaleX = rect.width / canvasRef.current!.width;
    const canvasScaleY = rect.height / canvasRef.current!.height;
    const startX = rect.left + clickedImage.x * canvasScaleX;
    const startY = rect.top + clickedImage.y * canvasScaleY;

    // 计算目标位置（屏幕中心往上100px）
    const targetX = (window.innerWidth - imgWidth) / 2;
    const targetY = (window.innerHeight - imgHeight) / 2 - 100;

    const animationData = {
      img: clickedImage,
      startX,
      startY,
      targetX,
      targetY,
      startTime: Date.now(),
      currentX: startX,
      currentY: startY,
      startScale: 1,
      targetScale: 1.2,
      currentScale: 1,
      startRotation: 0,
      targetRotation: 360,
      currentRotation: 0,
      trails: [
        { x: startX, y: startY, scale: 1, opacity: 0.6, delay: 0.1 },
        { x: startX, y: startY, scale: 1, opacity: 0.3, delay: 0.2 },
      ],
    };

    setAnimatingImage(animationData);

    // 开始动画
    const animate = () => {
      const elapsed = Date.now() - animationData.startTime;
      const progress = Math.min(elapsed / 500, 1); // 500ms动画时长

      // 使用easeOutCubic缓动函数
      const easeProgress = 1 - Math.pow(1 - progress, 3);
      const currentX = startX + (targetX - startX) * easeProgress;
      const currentY = startY + (targetY - startY) * easeProgress;
      const currentScale =
        animationData.startScale +
        (animationData.targetScale - animationData.startScale) * easeProgress;
      const currentRotation =
        animationData.startRotation +
        (animationData.targetRotation - animationData.startRotation) *
          easeProgress;

      // 更新拖影位置和缩放（有延迟效果）
      const updatedTrails = animationData.trails.map((trail) => {
        const trailProgress = Math.max(0, Math.min(1, progress - trail.delay));
        const trailEaseProgress =
          trailProgress > 0 ? 1 - Math.pow(1 - trailProgress, 3) : 0;
        const trailX = startX + (targetX - startX) * trailEaseProgress;
        const trailY = startY + (targetY - startY) * trailEaseProgress;
        const trailScale =
          animationData.startScale +
          (animationData.targetScale - animationData.startScale) *
            trailEaseProgress;
        return {
          ...trail,
          x: trailX,
          y: trailY,
          scale: trailScale,
        };
      });

      // 其他图片透明度逐渐变为0的动画
      imgDataRef.current.forEach((imgData) => {
        if (imgData.index !== clickedImage.index) {
          // 其他图片透明度逐渐变为0
          const currentOpacity = Math.max(1 - easeProgress, 0);
          imgData.opacity = currentOpacity;
        }
      });

      // 重绘canvas以显示透明度变化
      drawAll();

      // 更新动画状态
      setAnimatingImage((prev) =>
        prev
          ? {
              ...prev,
              currentX,
              currentY,
              currentScale,
              currentRotation,
              trails: updatedTrails,
            }
          : null
      );

      if (progress >= 1) {
        // 动画完成
        setAnimatingImage(null);
        return;
      }

      animationFrameRef.current = requestAnimationFrame(animate);
    };

    animate();
  };

  // 开始取消选中动画
  const startDeselectAnimation = (selectedImg: GameImgData) => {
    if (animatingImage) return; // 如果正在动画中，忽略

    const rect = canvasRef.current?.getBoundingClientRect();
    if (!rect) return;

    // 计算目标位置（canvas中图片的位置，考虑canvas的缩放）
    const canvasScaleX = rect.width / canvasRef.current!.width;
    const canvasScaleY = rect.height / canvasRef.current!.height;
    const targetX = rect.left + selectedImg.x * canvasScaleX;
    const targetY = rect.top + selectedImg.y * canvasScaleY;

    // 计算起始位置（屏幕中心往上100px）
    const startX = (window.innerWidth - imgWidth) / 2;
    const startY = (window.innerHeight - imgHeight) / 2 - 100;

    const animationData = {
      img: selectedImg,
      startX,
      startY,
      targetX,
      targetY,
      startTime: Date.now(),
      currentX: startX,
      currentY: startY,
      startScale: 1.2,
      targetScale: 1,
      currentScale: 1.2,
      startRotation: 360,
      targetRotation: 0,
      currentRotation: 360,
      trails: [
        { x: startX, y: startY, scale: 1.2, opacity: 0.6, delay: 0.1 },
        { x: startX, y: startY, scale: 1.2, opacity: 0.3, delay: 0.2 },
      ],
    };

    // 先清除选中状态，显示动画
    setAnimatingImage(animationData);

    // 开始动画
    const animate = () => {
      const elapsed = Date.now() - animationData.startTime;
      const progress = Math.min(elapsed / 400, 1); // 400ms动画时长（稍快一些）

      // 使用easeOutCubic缓动函数
      const easeProgress = 1 - Math.pow(1 - progress, 3);
      const currentX = startX + (targetX - startX) * easeProgress;
      const currentY = startY + (targetY - startY) * easeProgress;
      const currentScale =
        animationData.startScale +
        (animationData.targetScale - animationData.startScale) * easeProgress;
      const currentRotation =
        animationData.startRotation +
        (animationData.targetRotation - animationData.startRotation) *
          easeProgress;

      // 更新拖影位置和缩放（有延迟效果）
      const updatedTrails = animationData.trails.map((trail) => {
        const trailProgress = Math.max(0, Math.min(1, progress - trail.delay));
        const trailEaseProgress =
          trailProgress > 0 ? 1 - Math.pow(1 - trailProgress, 3) : 0;
        const trailX = startX + (targetX - startX) * trailEaseProgress;
        const trailY = startY + (targetY - startY) * trailEaseProgress;
        const trailScale =
          animationData.startScale +
          (animationData.targetScale - animationData.startScale) *
            trailEaseProgress;
        return {
          ...trail,
          x: trailX,
          y: trailY,
          scale: trailScale,
        };
      });

      // 同时进行其他图片的透明度恢复动画
      imgDataRef.current.forEach((imgData) => {
        if (imgData.index !== selectedImg.index) {
          // 其他图片透明度逐渐恢复到1
          imgData.opacity = easeProgress;
        }
      });

      // 重绘canvas以显示透明度变化
      drawAll();

      // 更新动画状态
      setAnimatingImage((prev) =>
        prev
          ? {
              ...prev,
              currentX,
              currentY,
              currentScale,
              currentRotation,
              trails: updatedTrails,
            }
          : null
      );

      if (progress >= 1) {
        setSelectedImage(null);
        // 动画完成，清除动画状态
        setAnimatingImage(null);
        // 确保所有图片都完全可见
        imgDataRef.current.forEach((imgData) => {
          imgData.opacity = 1;
        });
        drawAll();
        return;
      }

      animationFrameRef.current = requestAnimationFrame(animate);
    };

    animate();
  };

  useImperativeHandle(ref, () => ({
    startSelectAnimation,
    startDeselectAnimation,
    isAnimating: () => animatingImage !== null,
  }));

  return (
    <>
      {/* 动画中的拖影框 */}
      {/* {animatingImage?.trails?.map((trail, index) => (
        <div
          key={index}
          style={{
            position: "fixed",
            left: `${trail.x}px`,
            top: `${trail.y}px`,
            width: `${imgWidth}px`,
            height: `${imgHeight}px`,
            border: "4px solid gray",
            borderRadius: "10px",
            zIndex: 4 - index, // 拖影在后面
            pointerEvents: "none",
            opacity: trail.opacity,
            transform: `scale(${trail.scale})`,
            transformOrigin: "center center",
          }}
        />
      ))} */}

      {/* 动画中的图片 */}
      {animatingImage && (
        <img
          src={animatingImage.img.gameData.img}
          alt="animating image"
          style={{
            position: "fixed",
            left: `${animatingImage.currentX}px`,
            top: `${animatingImage.currentY}px`,
            width: `${imgWidth}px`,
            height: `${imgHeight}px`,
            borderRadius: "10px",
            zIndex: 5,
            pointerEvents: "none",
            transform: `scale(${animatingImage.currentScale}) rotateY(${animatingImage.currentRotation}deg)`,
            transformOrigin: "center center",
          }}
        />
      )}

      {/* 选中状态的UI展示 */}
      {selectedImage && !animatingImage && (
        <div
          style={{
            position: "absolute",
            top: 0,
            left: 0,
            width: "100%",
            height: "100%",
            zIndex: 5,
          }}
          onClick={() => selectedImage && startDeselectAnimation(selectedImage)}
        >
          {/* 固定位置的图片和文字容器 */}
          <div
            style={{
              position: "absolute",
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
              left: "50%",
              top: "50%",
              transform: "translate(-50%, calc(-50% - 100px))",
            }}
          >
            {/* 选中的图片 */}
            <img
              src={selectedImage.gameData.img}
              alt="selected image"
              style={{
                width: `${imgWidth}px`,
                height: `${imgHeight}px`,
                borderRadius: "10px",
                transform: "scale(1.2)",
                transformOrigin: "center center",
              }}
            />

            {/* 文字内容区域 - 绝对定位在图片下方 */}
            <div
              style={{
                position: "absolute",
                display: "flex",
                flexDirection: "column",
                alignItems: "center",
                top: `${imgHeight * 1.2}px`,
              }}
            >
              <div
                style={{
                  fontSize: "2rem",
                  fontWeight: "bold",
                  marginTop: "8px",
                  textAlign: "center",
                  whiteSpace: "nowrap",
                }}
              >
                {selectedImage.gameData.name}
              </div>

              <div
                style={{
                  fontSize: "1rem",
                  marginTop: "16px",
                  textAlign: "center",
                  whiteSpace: "nowrap",
                }}
              >
                {selectedImage.gameData.desc}
              </div>
            </div>
          </div>
        </div>
      )}
    </>
  );
});

AnimatingGameImage.displayName = "AnimatingGameImage";

export default AnimatingGameImage;
